图解源码之java锁的获取和释放(AQS)篇

补充threadLocal内存泄露问题

threadLocal总结:
1.为什么会泄露:,
由于ThreadLocalMap的生命周期跟Thread一样长,在Thread周期内 ,ThreadLocalMap 中key,value对象只增不减,如果都没有手动删除对应key,都会导致内存泄漏,但是jvm提供的一层保障。
2,jvm如何通过弱引用给我们提供了一层保障
设置ThreadLocalMap的key ThreadLocal对象为弱引用,当key不在被引用时,下次gc回收的时候threadlocal将被回收(即threadLocalMap的key被变为null)
当调用threadLocal,的get,set,remove方法时会清除threadLocalMap的key为空的对象,至此key,value都被回收,不会发生内存泄露
3,为什么jvm提供了保障还会出现内存泄露
线程长时间运行,比如在线程池里的线程,ThreadLocalMap 产生了大量key为null,的value对象,而又没有调用get,set,remove方法,以至于没有回收这些对象导致,
故ThreadLocal使用后务必调用remove方法,以防止内存泄露。

 

以独占式不公平锁为例,通过5个线程争夺ReentrantLock的过程,图解ReentrantLock源码实现,了解显示锁的工作流程。

 

 

 

任何时刻拿到锁的只有一个线程,未拿到锁的线程会打包成节点(node),然后将节点通过CAS自旋的方式,从队列尾部放入同步队列中。

 

 

 

增加尾节点为什么要用cas,因为会存在多个线程竞争尾节点。

 

 

 

以上便是线程竞争锁的过程,以及竞争失败之后需要做的全部事情。

 

以上便是线程获取和释放锁的全过程,可用如下流程图进行归纳。

 

 

另外,以上源码均来自jdk1.8,本文章作为梳理思路,仅摘要了关键部分,详细流程请读者跟着思路自行阅读源码,英文过关是阅读的必要技能之一,不然看不懂注释真的很蛋疼。。重要的事情说三遍,英文一定要好!

英文一定要好!英文一定要好!

 

posted @ 2018-07-10 13:29  开心的鱼a1  阅读(581)  评论(0编辑  收藏  举报